﻿using NetTopologySuite.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AgCIM.Tools.SpatialEncoding.Beidou
{
    public class BeidouBoundingBox
    {
        public double MinLon { get; set; }
        public double MaxLon { get; set; }
        public double MinLat { get; set; }
        public double MaxLat { get; set; }
        public double MinAlt { get; set; }
        public double MaxAlt { get; set; }

        public bool IsDegree { get; set; }

        public BeidouBoundingBox(Coordinate minObj, Coordinate maxObj, bool isDegree)
        {
            this.MinLon = minObj.Lng;
            this.MinLat = minObj.Lat;
            this.MaxLon = maxObj.Lng;
            this.MaxLat = maxObj.Lat;
            this.MinAlt = minObj.Alt ?? 0.0;
            this.MaxAlt = maxObj.Alt ?? 0.0;
            this.IsDegree = isDegree;
        }

        public BeidouBoundingBox ToRadians()
        {
            if (this.IsDegree)
            {
                var carMin = Cartographic.FromDegrees(this.MinLon, this.MinLat);
                var carMax = Cartographic.FromDegrees(this.MaxLon, this.MaxLat);

                this.MinLon = carMin.Longitude;
                this.MinLat = carMin.Latitude;
                this.MaxLon = carMax.Longitude;
                this.MaxLat = carMax.Latitude;

                this.IsDegree = false;
            }
            return this;
        }

        public BeidouBoundingBox CartesianToDegrees(Vector3D min, Vector3D max)
        {
            var minCartesian = Cartographic.FromCartesian3(min);
            var maxCartesian = Cartographic.FromCartesian3(max);

            this.MinLon = minCartesian.Longitude;
            this.MinLat = minCartesian.Latitude;
            this.MaxLon = maxCartesian.Longitude;
            this.MaxLat = maxCartesian.Latitude;
            this.MinAlt = minCartesian.Height;
            this.MaxAlt = maxCartesian.Height;
            this.IsDegree = true;

            return this;
        }

        public Cartographic GetCenter()
        {
            if (this.IsDegree)
            {
                var carMin = Cartographic.FromDegrees(this.MinLon, this.MinLat, this.MinAlt);
                var carMax = Cartographic.FromDegrees(this.MaxLon, this.MaxLat, this.MaxAlt);

                var centerX = (carMax.Longitude + carMin.Longitude) * 0.5;
                var centerY = (carMax.Latitude + carMin.Latitude) * 0.5;
                var centerZ = (carMax.Height + carMin.Height) * 0.5;

                var carCenter = new Cartographic(centerX, centerY, centerZ);
                var center = Cartographic.DegreeCartographic(carCenter);

                return center;
            }

            throw new InvalidOperationException("当前坐标格式不正确，请检查数据格式.");
        }

        public double GetLongitudeSpan()
        {
            return Math.Abs(this.MaxLon - this.MinLon);
        }

        public double GetLatitudeSpan()
        {
            return Math.Abs(this.MaxLat - this.MinLat);
        }

        public double GetHeightSpan()
        {
            return Math.Abs(this.MaxAlt - this.MinAlt);
        }
    }
}
